#include "StdAfx.h"
#include "DataBaseWrapper.h"
#include "sqlite3.h"
#pragma warning(disable: 4244)
#include "utf8.h"
#include <cstring>
using namespace std;
using namespace utf8;
namespace grid{
	DataBaseWrapper::DataBaseWrapper(void)
	{	
	}

	DataBaseWrapper::~DataBaseWrapper(void)
	{
		closeDatabase();
	}
	int DataBaseWrapper::openDatabase(const wstring &dbname)
	{
		char *zErrMsg = 0;
		string utf8Name;
		utf16to8(dbname.begin(), dbname.end(), back_inserter(utf8Name));
		int rc = sqlite3_open(utf8Name.c_str(), &m_db);
		if (rc) 
		{
			sqlite3_close(m_db);
			return rc;
		}
		return 0;
	}
	int DataBaseWrapper::exec(const wstring &statment, SqlResult &result, wstring &errmsg)
	{
		string utf8stat;
		utf16to8(statment.begin(), statment.end(), back_inserter(utf8stat));
		char **table;
		int nrow;
		int ncol;
		char *utf8ErrorMessage;
		int rc = sqlite3_get_table(m_db, utf8stat.c_str(), &table, &nrow, &ncol, &utf8ErrorMessage);
		if (rc != 0){
			utf8to16(utf8ErrorMessage, utf8ErrorMessage + strlen(utf8ErrorMessage), 
                       back_inserter(errmsg));
			return rc;
		}
		wstring wvalue;
		result.m_result.clear();
		int i = 0;
		result.m_result.resize(nrow + 1, vector< wstring>(ncol) );
		for (int y = 0; y< nrow+1; ++y){			
			for (int x = 0; x<ncol; ++x){
				char *utf8value = table[i++];
				utf8to16(utf8value, utf8value+strlen(utf8value), back_inserter( result.m_result[y][x] ));
			}
		}
        
		sqlite3_free_table(table);
		return 0;
	}
	int DataBaseWrapper::closeDatabase()
	{
		int rc = sqlite3_close(m_db);
		return rc;
	}
	int SqlResult::getRowCount()
	{
		return static_cast<int>(m_result.size()-1);
	}
	int SqlResult::setRow(int n)
	{
		if (n >= getRowCount()) return -1;
		m_row = n;
		return 0;
	}
	int SqlResult::getColumCount()
	{
		if (m_result.empty()) return 0;
		return static_cast<int>(m_result[0].size());
	}
	wstring SqlResult::getValue(int Colum)
	{
		return m_result.at(m_row+1).at(Colum);
	}
	int SqlResult::nextRow()
	{
		if (m_row < getRowCount()){
            m_row++;
			return 1;
		} else {
			return 0;
		}
	}
}